package com.licheedev.serialtool.comn;

import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import com.licheedev.hwutils.ByteUtil;
import com.licheedev.myutils.LogPlus;
import com.licheedev.serialtool.comn.message.LogManager;
import com.licheedev.serialtool.comn.message.RecvMessage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * 读串口线程
 */
public class SerialReadThread extends Thread {

    private static final String TAG = "SerialReadThread";

    private BufferedInputStream mInputStream;

    public SerialReadThread(InputStream is) {
        mInputStream = new BufferedInputStream(is);
    }

    @Override
    public void run() {
        byte[] received = new byte[1024];
        int size;

        LogPlus.e("开始读线程");

        while (true) {

            if (Thread.currentThread().isInterrupted()) {
                break;
            }
            try {

                int available = mInputStream.available();

                if (available > 0) {
                    sleep(500);
                    size = mInputStream.read(received);
                    if (size > 0) {
                        onDataReceive(received, size);
                    }
                } else {
                    // 暂停一点时间，免得一直循环造成CPU占用率过高
                    SystemClock.sleep(1);
                }
            } catch (Exception e) {
                LogPlus.e("读取数据失败", e);
            }
            //Thread.yield();
        }

        LogPlus.e("结束读进程");
    }

    /**
     * 处理获取到的数据
     *
     * @param received
     * @param size
     */
    private void onDataReceive(byte[] received, int size) {
        // TODO: 2018/3/22 解决粘包、分包等
        String hexStr = ByteUtil.bytes2HexStr(received, 0, size);
//        LogManager.instance().post(new RecvMessage(hexStr));
        String receiveData5G = new String(received, 0, size);
        Log.d("__receive","received = " + Arrays.toString(received) + " receiveData5G = "+receiveData5G + " hexStr = "+hexStr);

        if (receiveData5G.startsWith("stdz")){
//             0           1     2     3     4     5     6
            //7374647A 2C 00 2C 01 2C 19 2C 20 2C 00 2C 00 0D0A

//            hexStr = hexStr.substring(0,hexStr.length()-4).toUpperCase();
//
//            String [] spliteStr = hexStr.split("2C");
//            Log.d("__spliteStr-1",""+spliteStr.length);
//
//            for (int i = 0; i < spliteStr.length; i++) {
//                Log.d("__spliteStr-2",""+spliteStr[i]);
//            }
//
//            Long.parseLong(spliteStr[1], 16);

            dealMcuData(received,size);

        }else {
            LogManager.instance().post(new RecvMessage(receiveData5G));

        }

        //stdz,,,, ,,


    }
    public static final byte[] MCU_HEADER = {115, 116, 100, 122};
    public static final byte[] MCU_END = {13, 10};
    private final StringBuilder preStrSB = new StringBuilder();
    private final StringBuilder hexStrSB = new StringBuilder();
    private final StringBuilder lastStrSB = new StringBuilder();
    private final StringBuilder mcuStrBuilder = new StringBuilder();
    private boolean dealMcuData(byte[] buffer, int size) {

        //mcu数据头位置
        int headerIndex = getByteIndex(buffer, MCU_HEADER, 0);
        //mcu数据尾位置
        int endIndex = getByteIndex(buffer, MCU_END, headerIndex) + 2;

        //数据是否解析完毕（判断可以直接发出去还是需要进入下一个拦截器）
        boolean parseComplete = false;
        if (endIndex - headerIndex != size){
            try {
                if (headerIndex > 0){ //mcu数据之前还有数据

                    byte[] preByte = subBytes(buffer,0, headerIndex);
                    replaceSB(preStrSB,new String(preByte));//mcu数据前面的数据



                    if(!TextUtils.isEmpty(preStrSB.toString())){
                        LogManager.instance().post(new RecvMessage(preStrSB.toString()));
                    }
                }

                if (endIndex < size){
                    byte[] lastByte = subBytes(buffer, endIndex, (size - endIndex));
                    replaceSB(lastStrSB,new String(lastByte));//mcu数据后面的数据
                    if(!TextUtils.isEmpty(lastStrSB.toString())){
                        LogManager.instance().post(new RecvMessage(lastStrSB.toString()));
                    }
                }

                //mcu前面没有数据，说明mcu数据后面有粘包数据
                byte[] mcuByte = subBytes(buffer, headerIndex, (endIndex - headerIndex));
                replaceSB(hexStrSB,ByteUtil.bytes2HexStr(mcuByte, 0, mcuByte.length));


            }catch (Exception e){
                e.printStackTrace();
            }
        }
        else {

            parseComplete = true;
            replaceSB(hexStrSB,ByteUtil.bytes2HexStr(buffer, 0, size));

        }
        replaceSB(hexStrSB,hexStrSB.substring(0, hexStrSB.length()-4).toUpperCase());
        //2C是逗号
        String [] spliteStr = hexStrSB.toString().split("2C");

        clearSB(mcuStrBuilder);

        try {
            for (int i = 0; i < spliteStr.length; i++) {
                if (i == 0){
                    mcuStrBuilder.append(hexStringToString(spliteStr[i])); //stdz

                }else {
                    //2E是小数点
                    if (spliteStr[i].contains("2E")){
                        String[] versionSplit = spliteStr[i].split("2E");
                        mcuStrBuilder.append(Integer.parseInt(versionSplit[0],16))
                                .append(hexStringToString("2E"))
                                .append(Integer.parseInt(versionSplit[1],16));

                    }else {
                        try {
                            if (!TextUtils.isEmpty(spliteStr[i])){
                                mcuStrBuilder.append(Integer.parseInt(spliteStr[i],16));

                            }
                        }catch (Exception e){
                            mcuStrBuilder.append("0");

                            e.printStackTrace();
                        }
                    }
                }
                if (i < spliteStr.length - 1){
                    mcuStrBuilder.append(",");

                }
            }
            LogManager.instance().post(new RecvMessage(mcuStrBuilder.toString()));

        }catch (Exception e){
            e.printStackTrace();
        }
        return parseComplete;
    }

    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }
    public static void replaceSB(StringBuilder sb,Object...str){

        if (str.length > 1){
            for (int i = 0; i < str.length; i++) {
                if (i == 0){
                    sb.replace(0,sb.length(),(String) str[i]);
                }else {
                    sb.append(str[i]);
                }
            }
        }else {
            sb.replace(0,sb.length(),String.valueOf(str[0]));
        }
    }
    /**
     * 16进制转换成为string类型字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }
    
    public static int getByteIndex(byte[] fatherByte, byte[] childByte,int fatherByteStartIndex) {
        int index1 = fatherByteStartIndex;
        int index2 = 0;
        if(childByte!=null) {
            while(index1 < fatherByte.length) {
                int dsite = 0;
                while(fatherByte[index1+dsite]==childByte[index2+dsite]) {
                    if(index2+dsite+1>=childByte.length){
                        return index1;

                    }

                    dsite++;
                    if(index1+dsite>=fatherByte.length || index2+dsite>=childByte.length){
                        break;

                    }
                }
                index1++;
            }
            return -1;
        }
        else{
            return index1;
        }

    }
    public static void clearSB(StringBuilder sb){
        sb.delete(0,sb.length());
    }


    /**
     * 停止读线程
     */
    public void close() {

        try {
            mInputStream.close();
        } catch (IOException e) {
            LogPlus.e("异常", e);
        } finally {
            super.interrupt();
        }
    }
}
